/******************************************************************************
*	device/hid/keyboard.h
*	 by Alex Chadwick
*
*	A light weight implementation of the USB protocol stack fit for a simple
*	driver.
*
*	device/hid/keyboard.h contains definitions relating to keyboards.
******************************************************************************/
#ifndef _DEVICE_HID_KEYBOARD_H
#define _DEVICE_HID_KEYBOARD_H

#include <usbd/device.h>
#include <types.h>

//------------------------------------------------------------------------------
/**
	\brief The current state of keyboard modifier keys.

	Encapsulates the current state of the keyboard modifier keys. Strucutre
	mimics the most common keyboard ordering.
*/
typedef
	struct KeyboardModifiers {
		bool LeftControl  : 1;  // @0
		bool LeftShift    : 1;  // @1
		bool LeftAlt      : 1;  // @2
		bool LeftGui      : 1;  // @3 ('Windows' key)
		bool RightControl : 1;  // @4
		bool RightShift   : 1;  // @5
		bool RightAlt     : 1;  // @6 ('alt gr')
		bool RightGui     : 1;  // @7
	}
KeyboardModifiers;

//------------------------------------------------------------------------------
/**
	\brief The current state of keyboard leds.

	Encapsulates the current state of the keyboard leds. Strucutre mimics the
	most common lights and ordering. Not all keyboards may support all lights.
*/
typedef
	struct KeyboardLeds {
		bool NumberLock : 1;
		bool CapsLock   : 1;
		bool ScrollLock : 1;
		bool Compose    : 1;
		bool Kana       : 1;
		bool Power      : 1;
		bool Mute       : 1;
		bool Shift      : 1;
	}
KeyboardLeds;

//------------------------------------------------------------------------------
/** The DeviceDriver field in UsbDriverDataHeader for keyboard devices. */
#define DeviceDriverKeyboard  (0x4B424430)

/** The maximum number of keys a keyboard can report at once. Should be
	multiple of 2. */
#define KeyboardMaxKeys  (6)

//------------------------------------------------------------------------------
/**
	\brief Keyboard specific data.

	The contents of the driver data field for keyboard devices. Placed in
	HidDevice, as this driver is built atop that.
*/
typedef
	struct KeyboardDevice {
		UsbDriverDataHeader Header;                // Standard driver data header
		u32                 Index;                 // Keyboard arrays index (internal)
		u32                 KeyCount;              // Number of keys currently depressed
		u16                 Keys[KeyboardMaxKeys]; // Keys currently depressed
		KeyboardModifiers   Modifiers;             // Modifiers currently depressed
		KeyboardLeds        LedSupport;            // Supported LEDs
		HidParserField      *LedFields[8];         // Map LED-report-fields to LEDs
		HidParserField      *KeyFields[8 + 1];     // Map Input-report-fields to Inputs
		HidParserReport     *LedReport;            // LED report
		HidParserReport     *KeyReport;            // Input (Keys & Modifiers) report
	}
KeyboardDevice;

//------------------------------------------------------------------------------
Result  KeyboardAttach (UsbDevice* device, u32 interface) ;

u32  KeyboardCount (void) ;

Result  KeyboardSetLeds (u32 keyboardAddress, KeyboardLeds leds) ;

KeyboardLeds  KeyboardGetLedSupport (u32 keyboardAddress) ;

Result  KeyboardPoll (u32 keyboardAddress) ;

KeyboardModifiers  KeyboardGetModifiers (u32 keyboardAddress) ;

u32  KeyboardGetKeyDownCount (u32 keyboardAddress) ;

bool  KeyboadGetKeyIsDown (u32 keyboardAddress, u16 key) ;

u16  KeyboardGetKeyDown (u32 keyboardAddress, u32 index) ;

u32  KeyboardGetAddress (u32 index) ;

#endif // _DEVICE_HID_KEYBOARD_H
